<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //T1
        //第一步，先看同步：调用fn1函数，打印1，然后在fn1函数里面调用fn2函数，打印3，fn2函数里面有new Promise，是同步，打印4
        //第二步，看异步-微任务：fn2函数里面有promise的.then，所以打印5
        //第三步，看异步-宏任务：setTimeout 是规定的宏任务，所以最后打印2
        function fn1(){
            console.log(1);
            fn2();
        }
        function fn2(){
            setTimeout(()=>{
                console.log(2);
            },100);
            console.log(3);
            new Promise(function(res,rej){
                console.log(4);   
                res(5);
            }).then((res)=>{
                console.log(res);
            });
        }
        fn1(); 
        
       
        //T2
        setTimeout(()=>{
            console.log(1);
            setTimeout(()=>{
                console.log(2);
            },0);
            setTimeout(()=>{
                console.log(3);
            },0);
        },0);
        setTimeout(()=>{
            console.log(4);
        },0);
   
        /* 遇到定时器宏任务，将console.log(1)和两个setTimeout()加入宏任务队列，先不执行。
           又遇到定时器，将console.log(4)加入宏任务队列先不执行。
           同步代码执行完，无微任务，执行宏任务，先执行console.log(1),打印1，将console.log(2)\console.log(3) 加入宏任务队列先不执行。执行下一个宏任务console.log(4),打印4，再继续执行下一个宏任务console.log(2)，打印 2 ，再执行console.log(3)，打印 3 
        */



        //T3
        console.log("script start");
        setTimeout(()=>{
            console.log("timeout1");   //----setTimeout 是宏任务
        },10);
        new Promise((resolve)=>{
            console.log("promise1");  //----new Promise 是同步（new Date也是属于同步）
            resolve();
            setTimeout(()=>{
                console.log("timeout2"); //----setTimeout 是宏任务
            },10);
        }).then(()=>{
            console.log("then1");   //----.then 是promise的方法 所以是微任务
        });
        console.log("script end");
        /* 从上往下，先看同步，再看异步-微任务，再看异步-宏任务  
           遇到console.log("script start")，打印script start，遇到setTimeout宏任务，console.log("timeout1")于10ms后加入宏任务队列。
           遇到new Promise，直接执行console.log("promise1")，打印promise1。
           遇到setTimeout宏任务，将console.log("timeout2")于10ms后加入宏任务队列。
           遇到.then微任务，console.log("then1")等待执行，遇到console.log("script end")，打印script end。同步代码执行完，按序执行微任务。
           打印then1，微任务执行完。按序执行宏任务，先后打印timeout1、timeout2
        */

     

        //T4
        //从上往下看，先看同步，第一步是打印D，第二步调用async1函数，函数里面依次打印A,C,B,然后到new Promise，打印G，接着打印I
        //看异步-微任务：.then打印H
        //看异步-宏任务：setTimeout打印F
        async function async1(){
            console.log("A");
            async2();
            console.log("B");
        }
        async function async2(){
            console.log("C");
        }
        console.log("D");
        setTimeout(()=>{
            console.log("F");    //----setTimeout 是宏任务
        },0);
        async1();     
        new Promise((resolve)=>{
            console.log("G");    //----new Promise 是同步
            resolve();
        }).then(()=>{
            console.log("H");   //----.then 是promise的方法 所以是微任务
        });
        console.log("I");

     

        //T5
        //从上往下，先看同步，第一步调用haha函数，在函数里打印1，然后await xixi函数调用，打印3，回到haha函数里面打印2，4，然后调用heihei函数打印5，最后打印setTimeout的6
       async function haha() {
       console.log(1);
       //微任务
       await xixi();
       console.log(2);
       console.log(4);
       heihei();
      }
       async function xixi() {
         console.log(3);
         //宏任务
         setTimeout(() => {
           console.log(6);        //----setTimeout 是宏任务
         }, 0);
       }
       function heihei() {
         console.log(5);
       }
       haha();
   

    //T6

    async function async1() {
       console.log("async1 start");
       await async2();
       console.log("async1 end"); //----在async函数中，遇到await会继续执行其对应代码，而排在后面的代码放入微任务队列中，所以这里是微任务
    }
    async function async2() {
       console.log("async2");
    }

    console.log("script start");

    setTimeout(() => {
        console.log("setTimeout");
    }, 0);

    async1();

    new Promise(function (resolve) {
        console.log("promise1");   //----new Promise 是同步
        resolve();
    }).then(function () {
        console.log("promise2");    //----.then 是promise的方法 所以是微任务
    });

     //第一步打印 script start ，遇到定时器，是宏任务，先放着不执行
    // 然后执行 async1函数，先打印 "async1 start"，遇到await，先执行 async2函数，打印 async2 ，阻塞下面代码（即加入微任务列表），跳出去执行同步代码
    // 遇到neew Promis，直接执行，打印 promise1 ，遇到 .then()，是微任务，放到微任务列表等待执行，
    // 同步代码执行完，开始执行微任务，即 await下面的代码，打印 async1 end
    // 继续执行下一个微任务，即执行 then 的回调，打印 promise2
    // 微任务执行完，开始宏任务，打印 setTimeout

    </script>
</body>
</html>